package fun_Implement

import (
	"gitee.com/huanminabc/go-utils/common"
	"go-LineScriptCommand/container"
	"go-LineScriptCommand/global"
	"strconv"
	"strings"
)

func init() {
	var funs = []container.Fun{
		unix,
		unixMill,
		now,
		nowPart,
		nowPartDate,
		nowPartTime,
		toTime,
		toUnix,
		eqTime,
		addTime,
		subTime,
		addUnix,
		subUnix,
		subTimeTime,
		splitTime,
		dayTime,
		nowScopeTime,
		week,
		nextWeek,
	}
	//注册函数
	common.InsertSliceBatch(&funs)
	container.RegisterFunList(funs)
	container.RegisterType("date", funs)
}

// 获取秒时间戳
func unix(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 获取秒时间戳
用法: unix()
示例: unix() //返回秒时间戳
`
	}
	return strconv.FormatInt(common.Now(common.SECOND), 10)
}

// 获取毫秒时间戳
func unixMill(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 获取毫秒时间戳
用法: unixMill()
示例: unixMill() //返回毫秒时间戳
`
	}
	return strconv.FormatInt(common.Now(common.MILLISECOND), 10)
}

func now(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 获取当前时间
用法: now()
示例: now() 返回当前时间 yyyy-MM-dd HH:mm:ss
`
	}
	if len(args) != 0 {
		panic("now函数参数个数不对")
	}
	return common.Format(common.Now(common.SECOND), common.DateFormatType("yyyy-MM-dd HH:mm:ss"))
}

// 将时间戳转换为时间(格式化)
func toTime(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 将时间戳转换为时间(格式化)
用法: toTime(时间戳,格式化)
- 时间戳: 1600000000
- 格式化: yyyy-MM-dd HH:mm:ss  (支持格式同eqTime)
示例: toTime("1600000000","yyyy-MM-dd HH:mm:ss") //返回格式化时间
`
	}
	//如果管道有值,那么就将前一个管道的值给函数第一个
	if len(args) == 1 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
	}
	if len(args) != 2 {
		panic("unixToTime函数参数个数不对")
	}
	//拆分参数
	timestamp := args[0]
	format_ := args[1]
	i, err := strconv.ParseInt(timestamp, 10, 64)
	if err != nil {
		panic("toTime函数第一个参数必须是数字")
	}
	return common.Format(i, common.DateFormatType(format_))
}

// 将时间转换为时间戳
func toUnix(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 将时间转换为时间戳
用法: toUnix(时间,格式化)
- 时间: 2020-01-01 00:00:00
- 格式化: yyyy-MM-dd HH:mm:ss  (支持格式同eqTime)
示例: toUnix("2020-01-01 00:00:00","yyyy-MM-dd HH:mm:ss") //返回时间戳
`
	}
	//如果管道有值,那么就将前一个管道的值给函数第一个
	if len(args) == 1 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
	}
	if len(args) != 2 {
		panic("timeToUnix函数参数个数不对")
	}
	//拆分参数
	time_ := args[0]
	format_ := args[1]
	getDateFormatType := common.GetDateFormatType(format_)
	return strconv.FormatInt(common.Parse(time_, getDateFormatType, common.SECOND), 10)
}

func nowPart(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 获取当前时间的年月日时分秒
用法: nowPart()
示例: nowPart() //返回 年\n月\n日\n时\n分\n秒
`
	}
	if len(args) != 0 {
		panic("nowPart函数参数个数不对")
	}
	year, month, day, hour, minute, second := common.NowPart()
	var timeStr = strconv.Itoa(year) + global.LineBreak + strconv.Itoa(int(month)) + global.LineBreak + strconv.Itoa(day) +
		global.LineBreak + strconv.Itoa(hour) + global.LineBreak + strconv.Itoa(minute) + global.LineBreak + strconv.Itoa(second)
	return timeStr
}
func nowPartDate(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 获取当前时间的年月日
用法: nowPartDate()
示例: nowPartDate() //返回 年\n月\n日
`
	}
	if len(args) != 0 {
		panic("nowPartDate函数参数个数不对")
	}
	year, month, day := common.NowPartDate()
	var timeStr = strconv.Itoa(year) + global.LineBreak + strconv.Itoa(int(month)) + global.LineBreak + strconv.Itoa(day)
	return timeStr
}

func nowPartTime(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 获取当前时间的时分秒
用法: nowPartTime()
示例: nowPartTime() //返回 时\n分\n秒
`
	}
	if len(args) != 0 {
		panic("nowPartTime函数参数个数不对")
	}
	hour, minute, second := common.NowPartTime()
	var timeStr = strconv.Itoa(hour) + global.LineBreak + strconv.Itoa(minute) + global.LineBreak + strconv.Itoa(second)
	return timeStr
}

// 时间比较
func eqTime(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 时间比较 (只支持常用的时间格式)
用法: eqTime(时间1,时间2)
示例: 
1. eqTime("2020-01-01 00:00:00","2020-01-01 00:00:00") //返回0
2. eqTime("2020-01-01 00:00:00","2020-01-01 00:00:01") //返回-1
3. eqTime("2020-01-01 00:00:01","2020-01-01 00:00:00") //返回1
支持格式:
1. yyyy-MM-dd HH:mm:ss.SSS
2. yyyy-MM-dd HH:mm:ss
3. yyyy-MM-dd
4. HH:mm:ss.SSS
5. HH:mm:ss
6. yyyyMMddHHmmss
7. yyyyMMddHHmm
8. yyyyMMdd
9. yyyyMM
`
	}
	//如果管道有值,那么就将前一个管道的值给函数第一个
	if len(args) == 1 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
	}
	if len(args) != 2 {
		panic("eqTime函数参数个数不对")
	}
	//拆分参数
	time1 := args[0]
	time2 := args[1]
	return strconv.Itoa(common.EqTime(time1, time2, common.GetDateFormatType(time1)))
}

func nowScopeTime(args ...string) string {
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 判断当前时间是否在某个时间段内
用法: nowScopeTime(开始时间,结束时间)
示例: nowScopeTime('2020-01-01 00:00:00','2020-01-01 00:00:01') //返回true
`
	}
	//如果管道有值,那么就将前一个管道的值给函数第一个
	if len(args) == 1 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
	}
	if len(args) != 2 {
		panic("nowScopeTime函数参数个数不对")
	}
	//拆分参数
	startTime := args[0]
	endTime := args[1]
	return strconv.FormatBool(common.NowScopeTime(startTime, endTime, common.GetDateFormatType(startTime)))
}

// 时间加
func addTime(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 时间加
用法: addTime(时间,数量,单位)
- 时间: 2020-01-01 00:00:00
- 数量: 数字
- 单位: y(年),M(月),d(日),H(时),m(分),s(秒)  注意: 大小写
示例:(支持格式同eqTime)
1. addTime("2020-01-01 00:00:00",1,"y") //返回2021-01-01 00:00:00
2. addTime("2020-01-01 00:00:00",1,"M") //返回2020-02-01 00:00:00
`
	}
	//如果管道有值,那么就将前一个管道的值给函数第一个
	if len(args) == 2 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
	}
	if len(args) != 3 {
		panic("addTime函数参数个数不对")
	}
	//拆分参数
	time_ := args[0]
	num := args[1]
	unit := args[2]
	atoi, err := strconv.Atoi(num)
	if err != nil {
		panic("addTime函数第二个参数必须是数字")
	}
	getDateFormatType := common.GetDateFormatType(time_)
	return common.StrAddTime(time_, getDateFormatType, atoi, common.TimeUnit(unit))
}

// 时间减
func subTime(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 时间减
用法: subTime(时间,数量,单位)
- 时间: 2020-01-01 00:00:00
- 数量: 数字
- 单位: y(年),M(月),d(日),H(时),m(分),s(秒)  注意: 大小写
示例:(支持格式同eqTime)
1. subTime("2020-01-01 00:00:00",1,"y") //返回2019-01-01 00:00:00
2. subTime("2020-01-01 00:00:00",1,"M") //返回2019-12-01 00:00:00
`
	}
	//如果管道有值,那么就将前一个管道的值给函数第一个
	if len(args) == 2 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
	}
	if len(args) != 3 {
		panic("subTime函数参数个数不对")
	}
	//拆分参数
	time_ := args[0]
	num := args[1]
	unit := args[2]
	atoi, err := strconv.Atoi(num)
	if err != nil {
		panic("subTime函数第二个参数必须是数字")
	}
	getDateFormatType := common.GetDateFormatType(time_)
	return common.StrSubTime(time_, getDateFormatType, atoi, common.TimeUnit(unit))
}

// 时间戳加
func addUnix(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 时间戳加
用法: addUnix(时间戳,数量,单位)
- 时间戳: 1600000000
- 数量: 数字
- 单位: y(年),M(月),d(日),H(时),m(分),s(秒)  注意: 大小写
示例:
1. addUnix("1600000000",1,"y") //返回1610668800
2. addUnix("1600000000",1,"M") //返回1602681600
`
	}
	//如果管道有值,那么就将前一个管道的值给函数第一个
	if len(args) == 2 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
	}
	if len(args) != 3 {
		panic("addUnix函数参数个数不对")
	}
	//拆分参数
	timestamp := args[0]
	num := args[1]
	unit := args[2]
	i, err := strconv.ParseInt(timestamp, 10, 64)
	if err != nil {
		panic("addUnix函数第一个参数必须是数字")
	}
	atoi, err := strconv.Atoi(num)
	if err != nil {
		panic("addUnix函数第二个参数必须是数字")
	}
	return strconv.FormatInt(common.AddTime(i, atoi, common.TimeUnit(unit)), 10)
}

// 时间戳减
func subUnix(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 时间戳减
用法: subUnix(时间戳,数量,单位)
- 时间戳: 1600000000
- 数量: 数字
- 单位: y(年),M(月),d(日),H(时),m(分),s(秒)  注意: 大小写
示例:(支持格式同eqTime)
1. subUnix("1600000000",1,"y") //返回1588291200
2. subUnix("1600000000",1,"M") //返回1590969600
`
	}
	//如果管道有值,那么就将前一个管道的值给函数第一个
	if len(args) == 2 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
	}
	if len(args) != 3 {
		panic("subUnix函数参数个数不对")
	}
	//拆分参数
	timestamp := args[0]
	num := args[1]
	unit := args[2]
	i, err := strconv.ParseInt(timestamp, 10, 64)
	if err != nil {
		panic("subUnix函数第一个参数必须是数字")
	}
	atoi, err := strconv.Atoi(num)
	if err != nil {
		panic("subUnix函数第二个参数必须是数字")
	}
	return strconv.FormatInt(common.SubTime(i, atoi, common.TimeUnit(unit)), 10)
}

// 一个时间减去另一个时间,返回年月日时分秒
func subTimeTime(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 一个时间减去另一个时间, 返回相差的年月日时分秒
用法: subTimeTime(时间1,时间2)
示例:(支持格式同eqTime)
1. subTimeTime("2024-01-02 03:01:00","2023-01-01 01:00:00") //返回 1\n10\n1\n2\n1\n0
`
	}
	//如果管道有值,那么就将前一个管道的值给函数第一个
	if len(args) == 1 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
	}
	if len(args) != 2 {
		panic("subTimeTime函数参数个数不对")
	}
	//拆分参数
	time1 := args[0]
	time2 := args[1]
	getDateFormatType := common.GetDateFormatType(time1)
	year, month, day, hour, minute, second := common.StrSubStr(time1, time2, getDateFormatType)
	var timeStr = strconv.Itoa(year) + global.LineBreak + strconv.Itoa(int(month)) + global.LineBreak + strconv.Itoa(day) +
		global.LineBreak + strconv.Itoa(hour) + global.LineBreak + strconv.Itoa(minute) + global.LineBreak + strconv.Itoa(second)
	return timeStr
}

// 时间拆分,返回年月日时分秒
func splitTime(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 时间拆分,返回年月日时分秒
用法: splitTime(时间)
示例: splitTime("2020-01-01 00:00:00") //返回 年\n月\n日\n时\n分\n秒
`
	}
	//如果管道有值,那么就将前一个管道的值给函数第一个
	if len(args) == 0 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
	}
	if len(args) != 1 {
		panic("splitTime函数参数个数不对")
	}
	//拆分参数
	time_ := args[0]
	year, month, day, hour, minute, second, _ := common.SplitTime(time_)
	var timeStr = strconv.Itoa(year) + global.LineBreak + strconv.Itoa(int(month)) + global.LineBreak + strconv.Itoa(day) +
		global.LineBreak + strconv.Itoa(hour) + global.LineBreak + strconv.Itoa(minute) + global.LineBreak + strconv.Itoa(second)
	return timeStr
}

func dayTime(args ...string) string {
	//判断第一个参数是-doc
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 获取今天几时几分几秒的时间
用法: dayTime(时,分,秒)
示例: dayTime(9,30,0) 返回:2024-05-15 09:30:00
`
	}
	//如果有管道,那么就将管道的值给函数
	if len(args) == 0 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
		//拆解数据
		data := args[0]
		args = strings.Split(data, global.LineBreak)
		args[0] = strings.TrimSpace(args[0])
		args[1] = strings.TrimSpace(args[1])
		args[2] = strings.TrimSpace(args[2])
	}
	if len(args) != 3 {
		panic("dayTime函数参数个数不对")
	}
	//拆分参数
	hour := args[0]
	minute := args[1]
	second := args[2]
	atoi, err := strconv.Atoi(hour)
	if err != nil {
		panic("dayTime函数第一个参数必须是数字")
	}
	atoi1, err := strconv.Atoi(minute)
	if err != nil {
		panic("dayTime函数第二个参数必须是数字")
	}
	atoi2, err := strconv.Atoi(second)
	if err != nil {
		panic("dayTime函数第三个参数必须是数字")
	}
	return common.AtDayTime(atoi, atoi1, atoi2)

}

func week(args ...string) string {
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 获取本周几时几分几秒的时间
用法: week(周几,时,分,秒)
示例: week(1,9,30,0) 返回:2024-05-22 09:30:00
`
	}
	//如果有管道,那么就将管道的值给函数
	if len(args) == 0 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
		//拆解数据
		data := args[0]
		args = strings.Split(data, global.LineBreak)
		args[0] = strings.TrimSpace(args[0])
		args[1] = strings.TrimSpace(args[1])
		args[2] = strings.TrimSpace(args[2])
		args[3] = strings.TrimSpace(args[3])
	}
	if len(args) != 4 {
		panic("week函数参数个数不对")
	}
	//拆分参数
	week_ := args[0]
	hour := args[1]
	minute := args[2]
	second := args[3]
	atoi, err := strconv.Atoi(week_)
	if err != nil {
		panic("week函数第一个参数必须是数字")
	}
	atoi1, err := strconv.Atoi(hour)
	if err != nil {
		panic("week函数第二个参数必须是数字")
	}
	atoi2, err := strconv.Atoi(minute)
	if err != nil {
		panic("week函数第三个参数必须是数字")
	}
	atoi3, err := strconv.Atoi(second)
	if err != nil {
		panic("week函数第四个参数必须是数字")
	}

	return common.GetWeekTime(common.Weekday(atoi), atoi1, atoi2, atoi3)
}
func nextWeek(args ...string) string {
	if len(args) > 0 && args[0] == "-doc" {
		return `
功能: 获取下周几时几分几秒的时间
用法: nextWeek(周几,时,分,秒)
示例: nextWeek(1,9,30,0) 返回:2024-05-29 09:30:00
`
	}
	//如果有管道,那么就将管道的值给函数
	if len(args) == 0 && container.GetPrePipelineData().Data != "" {
		container.GetPrePipelineDataAndData(&args)
		//拆解数据
		data := args[0]
		args = strings.Split(data, global.LineBreak)
		args[0] = strings.TrimSpace(args[0])
		args[1] = strings.TrimSpace(args[1])
		args[2] = strings.TrimSpace(args[2])
		args[3] = strings.TrimSpace(args[3])
	}
	if len(args) != 4 {
		panic("nextWeek函数参数个数不对")
	}
	//拆分参数
	week_ := args[0]
	hour := args[1]
	minute := args[2]
	second := args[3]
	atoi, err := strconv.Atoi(week_)
	if err != nil {
		panic("nextWeek函数第一个参数必须是数字")
	}
	atoi1, err := strconv.Atoi(hour)
	if err != nil {
		panic("nextWeek函数第二个参数必须是数字")
	}
	atoi2, err := strconv.Atoi(minute)
	if err != nil {
		panic("nextWeek函数第三个参数必须是数字")
	}
	atoi3, err := strconv.Atoi(second)
	if err != nil {
		panic("nextWeek函数第四个参数必须是数字")
	}
	return common.GetNextWeekTime(common.Weekday(atoi), atoi1, atoi2, atoi3)
}
